package com.shuyun.hystrix.dynamic.archaius;

import com.netflix.config.AbstractPollingScheduler;
import com.netflix.config.PolledConfigurationSource;
import com.shuyun.hystrix.dynamic.config.ChangeEventType;
import com.shuyun.hystrix.dynamic.config.ConfigManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.configuration.Configuration;

/**
 * @description:
 * @author: shuai.chen@shuyun.com
 * @date: 2023/1/17 2:09 PM
 */
@Slf4j
public class CustomCfgPollingScheduler extends AbstractPollingScheduler {

    private final static String CONFIG_KEY_PREFIX = "hystrix";

    @Override
    public void startPolling(PolledConfigurationSource source, Configuration config) {
        super.startPolling(source, config);

        ConfigManager.addListener((item, type) -> {
            String name = item.getName();
            if(name.startsWith(CONFIG_KEY_PREFIX)) {
                String newValue = item.getValue();
                // 新增&修改
                if(ChangeEventType.ITEM_ADDED.equals(type) || ChangeEventType.ITEM_UPDATED.equals(type)) {
                    addOrChangeProperty(name, newValue, config);
                }
                // 删除
                else if(ChangeEventType.ITEM_REMOVED.equals(type)) {
                    deleteProperty(name, config);
                } else {
                    log.error("error config change event type {}.", type);
                }
            }
        });
    }

    private void addOrChangeProperty(String name, Object newValue, final Configuration config) {
        if (!config.containsKey(name)) {
            config.addProperty(name, newValue);
        } else {
            Object oldValue = config.getProperty(name);
            if (newValue != null) {
                if (!newValue.equals(oldValue)) {
                    config.setProperty(name, newValue);
                }
            } else if (oldValue != null) {
                config.setProperty(name, null);
            }
        }
    }

    private void deleteProperty(String key, final Configuration config) {
        if (config.containsKey(key)) {
            config.clearProperty(key);
        }
    }

    @Override
    protected void schedule(Runnable pollingRunnable) {
        // ignore code it
    }

    @Override
    public void stop() {
        // ignore code it
    }
}
